package org.gjy.m8.concurrent.lock;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 1a2b3c4d5e6f7g8h9i10j11k12l13m14n15o16p17q18r19s20t21u22v23w24x25y26z1a2b3c4d5e6f
 *
 * @author gjy
 * @version 1.0
 * @since 2025-10-13 17:04:14
 */
public class A1B2Print {

    private static final Lock LOCK = new ReentrantLock();
    private static final Condition number = LOCK.newCondition();
    private static final Condition character = LOCK.newCondition();
    private static final AtomicInteger single = new AtomicInteger(1);

    private static final AtomicInteger counter = new AtomicInteger(0);

    public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(3);

        pool.submit(() -> {
            LOCK.lock();
            try {
                while (!Thread.currentThread().isInterrupted()) {
                    if (single.get() % 2 == 0) {
                        number.await();
                    }
                    TimeUnit.MILLISECONDS.sleep(500);
                    System.out.print((counter.get() % 26) + 1);
                    single.incrementAndGet();
                    character.signal();
//                    Thread.currentThread().interrupt();
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                LOCK.unlock();
            }
        });

        pool.submit(() -> {
            LOCK.lock();
            try {
                while (!Thread.currentThread().isInterrupted()) {
                    if (single.get() % 2 != 0) {
                        character.await();
                    }
                    System.out.print((char) (counter.getAndIncrement() % 26 + 97));
                    single.incrementAndGet();
                    number.signal();
//                    Thread.currentThread().interrupt();
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                LOCK.unlock();
            }
        });

        pool.shutdown();
    }
}
